'use strict'

const path = require('path')
const npminstall = require('npminstall')
const fse = require('fs-extra')
const pathExists = require('path-exists').sync
const { isObject } = require('@djun-cli/utils')
const { getDefaultRegistry, getNpmLatestVersion } = require('@djun-cli/get-npm-info')
const formatPath = require('@djun-cli/format-path')
const log = require('@djun-cli/log')
const pkgDir = require('pkg-dir').sync

class Package {
  constructor(options) {
    if (!options) {
      throw new Error('Package类的options参数不能为空！')
    }
    if (!isObject(options)) {
      throw new Error('Package类的options参数必须为对象！')
    }
    // package 的路径
    this.targetPath = options.targetPath
    // 缓存的package 的路径
    this.storeDir = options.storeDir
    // packageName
    this.packageName = options.packageName
    // packageVersion
    this.packageVersion = options.packageVersion
    // package的缓存目录前缀
    this.cacheFilePathPreFix = this.packageName.replace('/', '_')
  }
  async prepare() {
    if (this.storeDir && !pathExists(this.storeDir)) {
      fse.mkdirpSync(this.storeDir)
    }

    if (this.packageVersion === 'latest') {
      try {
        this.packageVersion = await getNpmLatestVersion(this.packageName)
        log.verbose('this.packageVersion', this.packageVersion)
      } catch (e) {
        // console.log(e.message)
      }
    }
  }

  get cacheFilePath() {
    try {
      return path.resolve(this.storeDir, `_${this.cacheFilePathPreFix}@${this.packageVersion}@${this.packageName}`)
    } catch (e) {
      return ''
    }
  }
  getSpecificCacheFilePath(packageVersion) {
    return path.resolve(this.storeDir, `_${this.cacheFilePathPreFix}@${packageVersion}@${this.packageName}`)
  }
  // 判断当前package是否存在
  async exists() {
    if (!this.storeDir) {
      await this.prepare()
      log.verbose('this.cacheFilePath', this.cacheFilePath)
      return pathExists(this.cacheFilePath)
    } else {
      return pathExists(this.targetPath)
    }
  }
  // 安装package
  async install() {
    await this.prepare()
    return npminstall({
      root: path.resolve(this.targetPath),
      storeDir: path.resolve(this.storeDir),
      registry: getDefaultRegistry(),
      pkgs: [
        {
          name: this.packageName,
          version: this.packageVersion,
        },
      ],
    })
  }
  // 更新package
  async update() {
    await this.prepare()
    // 1.获取最新的版本号
    const latestPackageVersion = await getNpmLatestVersion(this.packageName)
    // 2.查询最新版本号对应的路径是否存在
    const latestFilePath = this.getSpecificCacheFilePath()
    // 3.如果不存在则直接安装最新版
    if (!pathExists(latestFilePath)) {
      await npminstall({
        root: path.resolve(this.targetPath),
        storeDir: path.resolve(this.storeDir),
        registry: getDefaultRegistry(),
        pkgs: [
          {
            name: this.packageName,
            version: latestPackageVersion,
          },
        ],
      })
      this.packageVersion = latestPackageVersion
    } else {
      this.packageVersion = latestPackageVersion
    }
  }
  // 获取入口文件的路径
  getRootFilePath() {
    function _getRootFile(targetPath) {
      // 1.获取package.json所在目录
      const dir = pkgDir(targetPath)
      if (dir) {
        // 2.读取package.json
        const pkgFile = require(path.resolve(dir, 'package.json'))
        // 3.寻找main/lib
        if (pkgFile && pkgFile.main) {
          // 4.路径兼容（macOS/windows）
          return formatPath(path.resolve(dir, pkgFile.main))
        }
      }
      return null
    }
    if (this.storeDir) {
      // 使用缓存的情况
      return _getRootFile(this.cacheFilePath)
    } else {
      return _getRootFile(this.targetPath)
    }
  }
}

module.exports = Package
